package cc.android.testapp.xp.hooker.adblock.core;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentActivity;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.ViewTreeObserver;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;

import com.google.gson.Gson;

import org.json.JSONObject;

import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;

import cc.android.testapp.util.CLog;
import cc.android.testapp.util.CTool;
import cc.android.testapp.xp.hooker.adblock.HookADBlock;
import cc.android.testapp.xp.hooker.adblock.track.SkipType;
import cc.android.testapp.xp.hooker.adblock.track.TrackHelper;
import cc.android.testapp.xp.hooker.adblock.util.ADBCfg;
import cc.commons.util.StringUtil;
import cc.commons.util.extra.CList;
import cc.commons.util.reflect.ClassUtil;
import cc.commons.util.reflect.FieldUtil;
import cc.commons.util.reflect.MethodUtil;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;

public class BlockAdAct {

    private static final ArrayList<Rect> mSkipButtonArea = new ArrayList<>();
    private static final Handler mHandler = new Handler(Looper.getMainLooper());
    /**
     * 缓存的广告规则
     * <p>一般情下,只允许AdRule.isAd()为true的时候,AdRule才能被加入缓存</p>
     */
    private static final HashMap<String, AdRule> mActRuleCache = new HashMap<>();
    private static final HashMap<String, ViewListener> mActOpMap = new HashMap<>();
    private static WeakReference<Object> mNowAct = null;


    private static final String[][] mKnewAdId = {new String[]{"com.sankuai.meituan.takeoutnew.ui.page.boot.WelcomeActivity", "ll_skip"}, new String[]{"com.sinovatech.unicom.basic.ui.MainActivity", "splash_advertise_close"}};
    private static final String[] mIgnoreRes = {"action", "gallery", "edit", "add", "sign", "title", "qrcode", "query", "search", "icon", "message", "setting", "scan", "notice", "menu", "tab", "manager", "mine", "home", "more"};


    public static void onHook(XC_LoadPackage.LoadPackageParam pParam) {
        hookActOnCreate(pParam);
        hookActOnResume(pParam);
        hookActOnPause(pParam);
    }

    private static void hookActOnResume(XC_LoadPackage.LoadPackageParam pParam) {
        XposedHelpers.findAndHookMethod(Activity.class, "onResume", new XC_MethodHook() {
            protected void afterHookedMethod(MethodHookParam pMParam) {
                mNowAct = new WeakReference<>(pMParam.thisObject);
                if (!HookADBlock.skipAd()) return;

                Activity tAct = (Activity) pMParam.thisObject;
                CLog.log("onResume: " + toStr(tAct));
                if (execCacheRule(tAct)) return;

                performClick(tAct);
            }
        });
    }

    public static void hookActOnCreate(XC_LoadPackage.LoadPackageParam pParam) {
        XposedHelpers.findAndHookMethod(Activity.class, "onCreate", Bundle.class, new XC_MethodHook() {
//            @Override
//            protected void beforeHookedMethod(MethodHookParam pMParam) throws Throwable {
//                if (!ADBCfg.skipAd()) return;
//
//                Activity tAct = (Activity) pMParam.thisObject;
//                AdRule tCfgRule = getRuleFromCfg(tAct);
//                if(tCfgRule.mSType==SkipType.FRAGMENT){
//                    // TODO 拦截Fragment
//                }
//
//                //缓存添加的Fragmen,用于button点击后对对应的Fragment进行删除
//
//            }

            protected void afterHookedMethod(MethodHookParam pMParam) {
                mNowAct = new WeakReference<>(pMParam.thisObject);
                if (!HookADBlock.skipAd()) return;

                Activity tAct = (Activity) pMParam.thisObject;
                CLog.log("onCreate: " + toStr(tAct));

                AdRule tCfgRule = getRuleFromCfg(tAct);
                if (tCfgRule.isAd()) {
                    mActRuleCache.put(tAct.getClass().getName(), tCfgRule);
                    if (execCacheRule(tAct)) return;
                }

                performClick(tAct);
            }
        });
    }

    private static boolean execCacheRule(Activity pAct) {
        AdRule tCacheR = mActRuleCache.get(pAct.getClass().getName());
        if (tCacheR == null || !tCacheR.isAd() || tCacheR.mSType == SkipType.BAN) return false;
        boolean tFinish = false;
        if (tCacheR.mSType == SkipType.FINISH_ACT) {
            pAct.finish();
            //CLog.log("通过执行finish()方法来跳过广告" + toStr(pAct));
            tFinish = true;
        } else if (tCacheR.mSType == SkipType.START_ACT) {
            Intent tIntent = tCacheR.getIntent();
            if (tIntent != null) {
                pAct.startActivity(tIntent);
                //CLog.log("通过执行startActivity方法来跳过广告" + toStr(pAct));
                tFinish = true;
            }
        } else if (tCacheR.mSType == SkipType.LISTENER) {
            Object tLis = TrackHelper.listeners.get(pAct.getClass().getName());
            if (tLis != null) {
                try {
                    String[] tArgs = tCacheR.mExtra.split("&");
                    View tView = TrackHelper.getViewGroup(pAct);
                    if (tLis instanceof View.OnClickListener) {
                        ((View.OnClickListener) tLis).onClick(tView);
                        tFinish = true;
                    } else if (tLis instanceof View.OnTouchListener) {
                        ((View.OnTouchListener) tLis).onTouch(tView, MotionEvent.obtain(0L,
                                0L, MotionEvent.ACTION_DOWN, 0F, 0F, 0));
                        tFinish = true;
                    }
                    //if (tFinish) CLog.log("直接执行跳过按钮监听器跳过广告");
                } catch (Throwable e) {
                    //CLog.log("直接执行跳过按钮监听器时发生错误", e);
                }

            } else {
                //CLog.log("Listener未实例化,无法直接执行");
            }
        } else if (tCacheR.mSType == SkipType.FRAGMENT && tCacheR.mFragmentJson != null) {
            try {
                JSONObject tJson = tCacheR.mFragmentJson;
                // 移除广告Fragment
                for (String sStr : new String[]{"remove", "hide", "show"}) {
                    if (!tJson.optBoolean(sStr)) continue;
                    int tRemoveId = tJson.optInt(sStr + "_fragment", -1);
                    if (tRemoveId == -1) continue;
                    String tFragmentClass = tJson.optString(sStr + "_fragment", "");
                    Object tFragment = null;
                    if (StringUtil.isNotEmpty(tFragmentClass) && (tFragment = TrackHelper.fragments.get(tFragmentClass)) != null) {
                        Object tTran = TrackHelper.beginTransaction(pAct);
                        Method tMethod = MethodUtil.getMethodIgnoreParam(tTran.getClass(), sStr, false).oneGet();
                        MethodUtil.invokeMethod(tMethod, tTran, tFragment);
                        MethodUtil.invokeMethod(tTran.getClass(), "commit", tTran);
                    }
                }
                // 显示主界面
                for (String sStr : new String[]{"add", "replace"}) {
                    if (!tJson.optBoolean(sStr)) continue;
                    String tFragmentClass = tJson.optString(sStr + "_fragment", "");
                    Object tFragment = null;
                    if (StringUtil.isNotEmpty(tFragmentClass) && (tFragment = TrackHelper.fragments.get(tFragmentClass)) != null) {
                        int tContainerId = tJson.optInt("container_id", 0);
                        String tFragmentTag = tJson.optString("fragment_tag");
                        Object tTran = TrackHelper.beginTransaction(pAct);
                        Method tMethod = MethodUtil.getDeclaredMethod(tTran.getClass(), (method) ->
                                method.getName().equals(sStr) && method.getParameterTypes().length == 3).oneGet();
                        MethodUtil.invokeMethod(tMethod, tTran, tContainerId, tFragment, tFragmentTag);
                        MethodUtil.invokeMethod(tTran.getClass(), "commit", tTran);
                    }
                }
                tFinish = true;
                CLog.log("隐藏开屏广告Fragment ");

            } catch (Throwable e) {
                CLog.log("跳过Fragment广告时发生错误", e);
            }

        }
        if (tFinish) {
            noticeAdSkip(pAct, "direct exec");
            removeFromOpList(pAct);
        }

        return tFinish;
    }

    private static AdRule getRuleFromCfg(Context pCon) {
        String tName = pCon.getClass().getName();

        AdRule tCfgR = AdRule.parseJson(ADBCfg.getRule(tName));
        if (!tCfgR.isAd()) {
            for (String[] sArr : mKnewAdId) {
                if (sArr[0].equals(tName)) {
                    tCfgR = new AdRule(pCon.getResources().getIdentifier(sArr[1], "id", pCon.getPackageName()), tName);
                    break;
                }
            }
        }
        CLog.log("读取配置->" + tCfgR + toStr(pCon));
        return tCfgR;
    }

//    private static @Nullable AdRule findNonameButton(Context context, ViewGroup pViewG) {
//        if (ignoreAct(context)) {
//            CLog.log("关键字activity跳过");
//            return null;
//        }
//
//        CLog.log("尝试检索无文字按钮:(" + context.getClass().getName() + ")");
//        ViewCache tViews = new ViewCache();
//        searchNoBlockView(tViews, pViewG);
//        CLog.log("view个数: " + context + " View: " + tViews.getViewNum() + " TextView: " + tViews.getTextNum());
//        if (tViews.isOverflow()) {
//            CLog.log("复杂界面跳过: " + context);
//        } else {
//            Rect tRect = new Rect();
//            ArrayList<View> tMatchViews = new ArrayList<>();
//            for (View sView : tViews.getViews()) {
//                int tId = sView.getId();
//                if (!sView.isShown() || !sView.isClickable() || tId == View.NO_ID)
//                    continue;
//
//                try {
//                    String resourceEntryName = sView.getResources().getResourceEntryName(tId);
//                    for (String sStr : mIgnoreRes) {
//                        if (resourceEntryName.contains(sStr)) continue;
//                    }
//                } catch (Exception ignored) {
//                    continue;
//                }
//                if ((tId & ViewCompat.MEASURED_STATE_MASK) != ViewCompat.MEASURED_STATE_TOO_SMALL) {
//                    sView.getGlobalVisibleRect(tRect);
//                    for (Rect sRect : mSkipButtonArea)
//                        if (sRect.contains(tRect)) {
//                            tMatchViews.add(sView);
//                        }
//                }
//            }
//
//            View tView = getBestAdButton(tMatchViews);
//            if (tView != null) return new AdRule(tView);
//        }
//        return null;
//    }


    private static View getBestAdButton(List<View> pViews) {
        if (pViews.size() > 1) {
            Collections.sort(pViews, (view, view2) -> {
                if (view.isShown() != view2.isShown()) return view.isShown() ? -1 : 1;
                if (view.isClickable() != view2.isClickable())
                    return view.isClickable() ? -1 : 1;

                if (view.getId() == View.NO_ID) return 1;
                return view2.getId() == View.NO_ID ? 1 : 0;
            });

        }

        return pViews.isEmpty() ? null : pViews.get(0);
    }


//    private static void searchNoBlockView(ViewCache pViews, ViewGroup viewGroup) {
//        for (int i = 0; i < viewGroup.getChildCount(); i++) {
//            View childAt = viewGroup.getChildAt(i);
//            if (!isViewCovered(i, viewGroup)) {
//                pViews.addView(childAt);
//                if (childAt instanceof ViewGroup) {
//                    searchNoBlockView(pViews, (ViewGroup) childAt);
//                }
//                if (pViews.isOverflow()) {
//                    return;
//                }
//            }
//        }
//    }

//    public static String STR = "";
//
//    private static boolean isViewCovered(int pTargetIndex, ViewGroup pViewG) {
//        View tChild = pViewG.getChildAt(pTargetIndex);
//        if (!tChild.isShown()) {
//            return true;
//        }
//        if ((tChild instanceof ViewGroup) && ((ViewGroup) tChild).getChildCount() == 0) {
//            return true;
//        }
//
//        STR = toStr(tChild);
//        Rect tRect = new Rect();
//        boolean tResult = tChild.getGlobalVisibleRect(tRect);
//        if (!(pViewG instanceof ScrollView)) {
//            tResult = tResult && (tRect.bottom - tRect.top >= tChild.getMeasuredHeight());
//            tResult = tResult && (tRect.right - tRect.left >= tChild.getMeasuredWidth());
//            if (!tResult) CLog.log(STR + "被父容器遮挡" + toStr(tChild));
//            if (!tResult) return true;
//        }
//        Rect tR2 = new Rect();
//        return isViewCovered(pTargetIndex + 1, pViewG, tRect);
//    }

//    private static boolean isViewCovered(int pStartPos, ViewGroup pViewG, Rect pBox) {
//        Rect tR2 = new Rect();
//        int tCount = pViewG.getChildCount();
//        for (int i = pStartPos; i < tCount; i++) {
//            View sChild = pViewG.getChildAt(i);
//            if (sChild.isShown() && sChild.getWidth() != 0 && sChild.getHeight() != 0) {
//                sChild.getGlobalVisibleRect(tR2);
//                if (tR2.contains(pBox))
//                    CLog.log(STR + "被兄弟View遮挡" + toStr(sChild));
//                if (tR2.contains(pBox)) return true;
//
//
//                if (sChild instanceof ViewGroup) {
//                    ViewGroup viewGroup2 = (ViewGroup) sChild;
//                    if (viewGroup2.getChildCount() == 0) {
//                        continue;
//                    } else if (isViewCovered(0, viewGroup2, pBox)) {
//                        return true;
//                    }
//                }
//            }
//        }
//        return false;
//    }


//    private static boolean ignoreAct(Context context) {
//        String tStr = context.getClass().getName().toLowerCase();
//        return tStr.contains("gallery") || tStr.contains("scan") || tStr.contains("picture") || tStr.contains("unity") || tStr.contains("image") || tStr.contains("webview");
//    }


    private static void performClick(Activity pAct) {
        AdRule tCacheR = mActRuleCache.get(pAct.getClass().getName());
        if (tCacheR != null && tCacheR.mSType == SkipType.BAN) return;

        initClickButtonArea(pAct);
        ViewListener tLis = new ViewListener(pAct);
        ViewListener tOld = mActOpMap.put(pAct.getClass().getName(), tLis);
        if (tOld != null) tOld.setExpired();
        tLis.searchAd();
        //pViewG.getViewTreeObserver().addOnGlobalLayoutListener(tLis);
        //
        Handler tH = new Handler(Looper.myLooper());
        tH.postDelayed(new Runnable() {
            @Override
            public void run() {
                if (!tLis.autoTrigger && !tLis.isExpired()) {
                    tLis.searchAd();
                    tH.postDelayed(this, 100L);
                }
            }
        }, 100L);
    }


    public static String toStr(Context pContext) {
        return " (Activity: " + pContext.getClass().getName() + ")";
    }

    public static String toStr(View pView) {
        String tStr = " (View: " + pView.getClass().getName();
        if (pView.getId() != View.NO_ID) {
            tStr += ", id: " + getViewId(pView.getContext(), pView.getId());
        } else {
            tStr += "(no id)";
        }
        if (pView instanceof TextView) {
            tStr += "(Text:" + ((TextView) pView).getText() + ")";
        }
        return tStr + ")";
    }

    public static String getViewId(Context pCont, int pView) {
        try {
            return pCont.getResources().getResourceEntryName(pView);
        } catch (Resources.NotFoundException ignored) {
            return null;
        }
    }

    public static void noticeAdSkip(Context context, String pExtra) {
        if (HookADBlock.mEnableSkipToast)
            Toast.makeText(context, "TA-消灭了一个广告(" + pExtra + ") ", Toast.LENGTH_SHORT).show();

    }

    public static void findSkipButton(List<View> pViews, ViewCache pResult, String pPrefix) {
        pViews.forEach((v) -> findSkipButton(v, pResult, pPrefix));
    }

    private static void findSkipButton(View pView, ViewCache pResult, String pPrefix) {
        View tView;
        //Rect tRect = new Rect();


        //if (!isViewCovered(sChild, i, pViewG, pPrefix)) {
        //CLog.log("View Rect: " + pPrefix + "not covered");

        if (pView instanceof ViewGroup && !(pView instanceof ScrollView)) {
            //CLog.log("View Rect: " + pPrefix + "(in)" + toStr(sChild));
            ViewGroup tCG = (ViewGroup) pView;
            int tCount = tCG.getChildCount();
            for (int i = 0; i < tCount; i++) {
                findSkipButton(tCG.getChildAt(i), pResult, pPrefix + "-");
            }
        } else {
            if (pView == null || !pView.isShown() || !pView.getGlobalVisibleRect(mRectNow)) return;
            //CLog.log("View: " + toStr(pView) + mRectNow + "|" + pView.getZ());
            pResult.addView(pView);
            if (pResult.isOverflow()) return;
            if ((tView = getSkipButton(pView)) != null) {
                pResult.addButton(tView);
                CLog.log("Button: " + mRectNow);
            }
        }
        //}

    }

    //private static Rect mCoverLast = new Rect();
    private static Rect mRectNow = new Rect();

    public static @Nullable View getSkipButton(View pView) {
        if (!(pView instanceof TextView)) return null;
        TextView textView = (TextView) pView;

        if (isSkipButton(textView))
            return getClickabelParent(pView, false);
        return null;
    }

    public static boolean isSkipButton(TextView pView) {
        //CLog.log(toStr(pView, pView.getContext()) + "判定开始");
        String tText = pView.getText().toString().trim().replace(" ", "");
        if (tText.length() > 7) {
            //CLog.log(toStr(pView, pView.getContext()) + "未通过长度判定,结束");
            return false;
        }

        boolean tbutton = false;
        for (String sStr : HookADBlock.STR_SKIP)
            if (tText.contains(sStr)) {
                CLog.log(toStr(pView) + "通过文本判定");
                tbutton = true;
                break;
            }

        //if (!tbutton) CLog.log(toStr(pView, pView.getContext()) + "未通过文本判定");
        if ((!tbutton) && (!HookADBlock.STR_TIME_SKIP.matcher(tText).matches())) {
            //CLog.log(toStr(pView, pView.getContext()) + "未通过时间文本判定,结束");
            return false;
        }

        Rect tRect = new Rect();
        pView.getGlobalVisibleRect(tRect);
        if (tRect.left > mAreaRightTop.x && tRect.bottom < mAreaRightTop.y) {
            CLog.log(toStr(pView) + "通过区域判定1");
            return true;
        }
        if (tRect.left > mAreaRightBottom.x && tRect.top > mAreaRightBottom.y) {
            CLog.log(toStr(pView) + "通过区域判定2");
            return true;
        }
        if (tRect.right < mAreaLeftBottom.x && tRect.top > mAreaLeftBottom.y) {
            CLog.log(toStr(pView) + "通过区域判定3");
            return true;
        }
        CLog.log(toStr(pView) + "未通过区域判定_结束");
        return false;
    }

    private static View getClickabelParent(View pView, boolean pAllowInvisible) {
        if (pView == null) return null;
        if (pView.isClickable()) return pView;

        if (pView.isShown() || pAllowInvisible) {
            ViewParent pParent = pView.getParent();
            if (pParent instanceof View) {
                return getClickabelParent((View) pParent, pAllowInvisible);
            }
        }
        return null;
    }

    private static Point mAreaRightTop;
    private static Point mAreaLeftBottom;
    private static Point mAreaRightBottom;

    private static void initClickButtonArea(Context context) {
        DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
        int tW = displayMetrics.widthPixels;
        int tH = displayMetrics.heightPixels;


        Rect tRect;
        mSkipButtonArea.add(tRect = new Rect((int) (tW * 0.6f), 0, tW, (int) (tH * 0.2f))); //right top
        mAreaRightTop = new Point(tRect.left, tRect.bottom);
        mSkipButtonArea.add(tRect = new Rect(0, (int) (tH * 0.8), (int) (tW * 0.4), tH)); //left bottom
        mAreaLeftBottom = new Point(tRect.right, tRect.top);
        mSkipButtonArea.add(tRect = new Rect((int) (tW * 0.6f), (int) (tH * 0.8), tW, tH)); //right bottom
        mAreaRightBottom = new Point(tRect.left, tRect.top);

    }

    public static void removeFromOpList(Context context) {
        mActOpMap.remove(context.getClass().getName());
    }


    private static void hookActOnPause(XC_LoadPackage.LoadPackageParam loadPackageParam) {
        XposedHelpers.findAndHookMethod(Activity.class, "onPause", new XC_MethodHook() {
            protected void beforeHookedMethod(MethodHookParam pMParam) {
                if (!HookADBlock.skipAd()) return;

                Activity activity = (Activity) pMParam.thisObject;
                String name = activity.getClass().getName();
                ViewListener tOld = mActOpMap.remove(name);
                if (tOld != null) tOld.setExpired();

                //CLog.log("onPause:" + toStr(activity));
            }
        });
    }

    static class ViewListener implements ViewTreeObserver.OnGlobalLayoutListener {

        private Activity mAct;
        public final long mAddTime = System.currentTimeMillis();
        private boolean mExpired = false;
        public boolean autoTrigger = false;
        private int amount = 0;

        public ViewListener(Activity pCon) {
            this.mAct = pCon;
        }

        public boolean isExpired() {
            return System.currentTimeMillis() - this.mAddTime > 15000 || this.mExpired;
        }

        public void setExpired() {
            this.mExpired = true;
        }

        public void searchAd() {
            amount++;
            if (this.isExpired()) {
                CLog.log("over time：" + toStr(mAct));
                mAct = null;
                return;
            }
            //CLog.log("开始检索按钮(自动触发: " + this.autoTrigger + ",次数: " + this.amount + ")");

            AdRule tCacheR = mActRuleCache.get(mAct.getClass().getName());
            int pViewId = tCacheR == null ? View.NO_ID : tCacheR.getViewId();
            View tButton = null;

            ArrayList<View> tViews = TrackHelper.getAllViews(this.mAct);
            if (pViewId != View.NO_ID && !tViews.isEmpty()) {
                tButton = TrackHelper.findView(tViews, pViewId);
                if (tButton != null) {
                    CLog.log("从缓存规则获取到按钮: " + toStr(tButton));
                } else {
                    CLog.log("缓存的规则按钮不存在");
                }
            }

            if (tButton == null) {
                tCacheR = null; //缓存规则无效,制空
                ViewCache tCacheV = new ViewCache();
                //CLog.log("find skip button start");
                findSkipButton(tViews, tCacheV, "-");
                //CLog.log("find skip button end " + tCacheV);
                if (!tCacheV.getButtonViews().isEmpty()) {
//                    CLog.log("收集到的按钮: ");
//                    for (View sView : tCacheV.getButtonViews()) {
//                        CLog.log(toStr(sView));
//                    }
                }
                if (tCacheV.isOverflow()) {
                    CLog.log("复杂界面退出:" + toStr(mAct));
                    this.setExpired();
                } else {
                    tButton = getBestAdButton(tCacheV.getButtonViews());
                }
                if (tButton != null) {
                    CLog.log("实时搜索获取到了按钮:" + toStr(tButton));
                }
            }
            if (tButton == null) {
                //else CLog.log("未点击, View is null" + toStr(mCon));
                return;
            }

            boolean tSuccess;
            boolean tTrack = tCacheR == null || tCacheR.mSType != SkipType.CLICK_BUTTON_NOTRACK;
            tTrack=false;
            if (tTrack) {
                TrackHelper.startTrack(mAct, new AdRule(tButton), this::replaceRule);
            }

            try {
                tSuccess = tButton.performClick();
//                TextView v;
//                v.setOnClickListener();
                CLog.log("点击" + toStr(tButton) + " Result: " + tSuccess + toStr(mAct));

//                Object tLisInfo = MethodUtil.invokeDeclaredMethod(View.class, "getListenerInfo", tButton);
//                CLog.log("所有的监听器: \n" + CTool.fieldVToStrV(tLisInfo));
//                CList<Field> tFields = FieldUtil.getDeclaredField(tLisInfo.getClass(), (pField) -> !Modifier.isStatic(pField.getModifiers()));
//                for (Field sField : tFields) {
//                    if (!View.OnTouchListener.class.isAssignableFrom(sField.getType()) &&
//                            !View.OnClickListener.class.isAssignableFrom(sField.getType())) {
//                        continue;
//                    }
//                    Object tLis = FieldUtil.getFieldValue(sField, tLisInfo);
//                    if (tLis == null) continue;
//                    AdRule tRule = new AdRule(tButton);
//                    tRule.mSType = SkipType.LISTENER;
//                    tRule.mExtra = tLis.getClass().getName();
//                    tRule.mExtra += "&" + "233";
//                    replaceRule(tRule);
//                    return;
//                }

                this.setExpired();
            } finally {
                if (tTrack) {
                    TrackHelper.finishTrack();
//                    new Handler(Looper.getMainLooper()).postDelayed(() -> {
//                        // 在5秒后判定当前Act在点击按钮后是否为同一个act,如果是,那么下一次在按钮点击后就不需要进行跟踪
//                        if (mNowAct != null && mAct == mNowAct.get()) {
//                            AdRule tt = mActRuleCache.get(mAct.getClass().getName());
//                            if (tt != null && tt.mSType == SkipType.CLICK_BUTTON) {
//                                AdRule ttn = tt.copy();
//                                ttn.mSType = SkipType.CLICK_BUTTON_NOTRACK;
//                                replaceRule(ttn);
//                            }
//                        }
//                    }, 5000);
                }
            }

            if (tSuccess) {
                mHandler.postDelayed(tButton::performClick, 250L); //防止检测多点两次
                noticeAdSkip(mAct, "click");
                removeFromOpList(mAct);
                if (!tTrack && tButton.getId() != View.NO_ID) {
                    replaceRule(new AdRule(tButton));
                }
            }
        }

        @Override
        public void onGlobalLayout() {
            autoTrigger = true;
            searchAd();
        }

        private void replaceRule(AdRule pNew) {
            String tKey = mAct.getClass().getName();
            AdRule pCache = mActRuleCache.get(tKey);
            CLog.log("Cache: " + pCache + "|New: " + pNew);

            AdRule tSaveT = null;
            if (pCache == null) {
                tSaveT = pNew;
            } else {
                if (pCache.mSType == SkipType.CLICK_BUTTON_NOTRACK) {
                    pNew.mSType = pCache.mSType;
                }

                if (!pCache.equals(pNew)) tSaveT = pNew;
            }

            if (tSaveT != null) {
                CLog.log("保存新配置: " + tSaveT + toStr(mAct));
                mActRuleCache.put(tKey, tSaveT);
                ADBCfg.saveRule(tKey, tSaveT.paserToJson());
            }
        }
    }

}
